package com.xqboss.web.controller.order;

import com.xqboss.apps.convert.order.OrderConverter;
import com.xqboss.apps.convert.user.UserConverter;
import com.xqboss.apps.domain.order.OrderMain;
import com.xqboss.apps.domain.order.OrderRefund;
import com.xqboss.apps.domain.order.PayApply;
import com.xqboss.apps.dto.IdDto;
import com.xqboss.apps.dto.order.*;
import com.xqboss.apps.enums.order.RefundStatusEnum;
import com.xqboss.apps.service.order.OrderRefundService;
import com.xqboss.apps.service.order.OrderService;
import com.xqboss.apps.service.order.PayApplyService;
import com.xqboss.apps.vo.order.WebOrderDetailVo;
import com.xqboss.apps.vo.sys.SysUserVo;
import com.xqboss.common.annotation.Log;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.core.domain.entity.SysUser;
import com.xqboss.common.enums.BusinessType;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 订单控制器
 * </p>
 *
 * @author Trent
 * @date 2023/8/23
 */
@Slf4j
@Api(tags = "订单-用户订单管理")
@RestController("WebOrderRefundController")
@RequestMapping("/web/order/refund")
public class OrderRefundController extends BaseController {

    @Autowired
    private OrderRefundService orderRefundService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderConverter orderConverter;

    @Autowired
    private PayApplyService payApplyService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private UserConverter userConverter;

    @PreAuthorize("@ss.hasPermi('web:order:refund:list')")
    @ApiOperation("获取退款列表")
    @GetMapping("list")
    public R<List<OrderRefund>> refundList(@Validated GetRefundListDto request) {
        if (Objects.isNull(request.getOrderByColumn())) {
            request.setOrderByColumn("id");
            request.setSortAsc(false);
        }
        request.startPageAndOrder();
        List<OrderRefund> list = orderRefundService.getRefundList(request);
        return R.ok(list);
    }

    @PreAuthorize("@ss.hasPermi('web:order:refund:detail')")
    @ApiOperation("获取退款详情")
    @GetMapping("detail/{refundId}")
    public R<OrderRefund> refundList(@Validated @PathVariable("refundId")
                                     @ApiParam(value = "退单ID", required = true)
                                     @NotNull(message = "退单ID不能为空")
                                     Long refundId) {
        OrderRefund detail = orderRefundService.getRefund(refundId);
        // 获取订单信息
        OrderMain orderDetail = orderService.getOrderDetail(detail.getOrderMainId(), null);
        PayApply payApply = null;
        if (Objects.nonNull(orderDetail.getPayOrderNo())) {
            // 如果支付流水不为空，则获取支付信息
            payApply = payApplyService.getById(orderDetail.getPayOrderNo());
        }
        SysUser user = userService.selectUserById(orderDetail.getBuyerUserId());
        SysUserVo sysUserVo = userConverter.toSysUserVo(user);
        WebOrderDetailVo detailVo = orderConverter.toWebOrderDetailVo(orderDetail, null);
        detailVo.setBuyerInfo(sysUserVo);
        detailVo.setPayInfo(payApply);

        detail.setOrderInfo(detailVo);
        return R.ok(detail);
    }


    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:order:refund:apply')")
    @ApiOperation("申请退款")
    @PostMapping("apply")
    @Log(title = "退单", businessType = BusinessType.INSERT)
    public R refundApply(@Validated @RequestBody ApplyRefundDto request) {
        orderRefundService.applyRefund(request);
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:order:refund:revoke')")
    @ApiOperation("撤销退款")
    @PutMapping("revoke")
    @Log(title = "退单", businessType = BusinessType.UPDATE)
    public R revoke(@Validated @RequestBody IdDto request) {
        orderRefundService.revokeRefund(request.getId());
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:order:refund:handler')")
    @ApiOperation("退款处理")
    @PutMapping("handler")
    @Log(title = "退单", businessType = BusinessType.UPDATE)
    public R refund(@Validated @RequestBody HandlerRefundDto request) {
        if (request.getStatus() != RefundStatusEnum.REFUND
                && request.getStatus() != RefundStatusEnum.CANCEL
                && request.getStatus() != RefundStatusEnum.ABORT) {
            throw new ServiceException("处理状态错误！");
        }

        if (request.getStatus() == RefundStatusEnum.CANCEL) {
            orderRefundService.revokeRefund(request.getId());
        } else {
            if (request.getStatus() == RefundStatusEnum.REFUND) {
                if (Objects.isNull(request.getRefundAmount())) {
                    throw new ServiceException("请输入实际退款金额！");
                }
                if (request.getRefundAmount().compareTo(BigDecimal.ZERO) < 0) {
                    throw new ServiceException("退款金额不能小于0!");
                }
            } else {
                request.setRefundAmount(null);
            }
            orderRefundService.handlerRefund(request);
        }
        return R.ok();
    }
}
